package com.zealsinger.nacos.learn.phonerepairfontbacken.config;


import com.zealsinger.nacos.learn.phonerepairfontbacken.security.AccessDeniedHandlerImpl;
import com.zealsinger.nacos.learn.phonerepairfontbacken.security.CorsFilter;
import com.zealsinger.nacos.learn.phonerepairfontbacken.security.TokenAuthenticationFilter;
import com.zealsinger.nacos.learn.phonerepairfontbacken.security.UnAuthorizedRequestHandler;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;


@Configuration
//@EnableWebSecurity
public class SecurityConfig {
    @Resource
    private TokenAuthenticationFilter tokenAuthenticationFilter;
    @Resource
    private UnAuthorizedRequestHandler unAuthorizedRequestHandler;
    @Resource
    private CorsFilter corsFilter;
    @Resource
    private AccessDeniedHandlerImpl accessDeniedHandler;
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        httpSecurity.csrf(AbstractHttpConfigurer::disable)
                .cors(AbstractHttpConfigurer::disable)
                .sessionManagement(
                        sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                );
        httpSecurity.authorizeHttpRequests(
                authorizeRequests -> authorizeRequests
                        .requestMatchers("/user/login","/test/login").permitAll()
                        .requestMatchers(HttpMethod.OPTIONS).permitAll()
                        .requestMatchers("/admin/**").hasAnyRole("ADMIN","AUDITOR","FINDER")
                        .requestMatchers("/user/**").hasAnyRole("USER","FINDER")
                        .anyRequest().authenticated()
        );
        httpSecurity.exceptionHandling(
                exceptionHandling -> exceptionHandling
                        .authenticationEntryPoint(unAuthorizedRequestHandler)
                        .accessDeniedHandler(accessDeniedHandler)
        );
        httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class);
        httpSecurity.addFilterBefore(tokenAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        return httpSecurity.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception {
        return authenticationConfiguration.getAuthenticationManager();
    }
    @Bean
    public PasswordEncoder passwordEncoder() {
      return new BCryptPasswordEncoder();
    }
}